#include <Interrapt.h>
#include <Proc.h>
#include <asm.h>

uint32	INT_ERR;

struct IDTR_S IDTR, SIDTR;

dummyInterrapt(0);dummyInterrapt(1);dummyInterrapt(2);dummyInterrapt(3);
dummyInterrapt(4);dummyInterrapt(5);dummyInterrapt(6);dummyInterrapt(7);
dummyInterrapt(8);dummyInterrapt(9);dummyInterrapt(10);dummyInterrapt(11);
dummyInterrapt(12);dummyInterrapt(13);dummyInterrapt(14);dummyInterrapt(15);
dummyInterrapt(16);dummyInterrapt(17);dummyInterrapt(18);dummyInterrapt(19);
dummyInterrapt(20);dummyInterrapt(21);dummyInterrapt(22);dummyInterrapt(23);
dummyInterrapt(24);dummyInterrapt(25);dummyInterrapt(26);dummyInterrapt(27);
dummyInterrapt(28);dummyInterrapt(29);dummyInterrapt(30);dummyInterrapt(31);


void Interrapt::setInterrapt(void (*i_addr)(), uint8 i_nr, uint8 i_type){
	IDT[i_nr].looffset = (uint16)((uint32)i_addr);
	IDT[i_nr].selector = SYS_CODE_SEL;
	IDT[i_nr].reserved = 0;
	IDT[i_nr].type = i_type;
	IDT[i_nr].dpl = UPL;
	IDT[i_nr].present = 1;
	IDT[i_nr].hioffset = (uint16)((uint32)i_addr >> 16);
}

void Interrapt::loadIDTR(){
	IDTR.p[0] = IDT_SIZE;
	IDTR.p[1] = (uint16)((uint32)IDT);
	IDTR.p[2] = (uint16)((uint32)IDT >> 16);
	asm("lidt IDTR");
}

void * Interrapt::operator new(size_t sz, void *addr){
	kprintf("ADDR: %X %i\n", addr, sizeof(InterraptGate));
	//for(;;);
	return addr;
}

void Interrapt::setNullInts(){
	setInterrapt(&dummyInterrapt0, 0, SD_486INTGT);
	setInterrapt(&dummyInterrapt1, 1, SD_486INTGT);
	setInterrapt(&dummyInterrapt2, 2, SD_486INTGT);
	setInterrapt(&dummyInterrapt3, 3, SD_486INTGT);
	setInterrapt(&dummyInterrapt4, 4, SD_486INTGT);
	setInterrapt(&dummyInterrapt5, 5, SD_486INTGT);
	setInterrapt(&dummyInterrapt6, 6, SD_486INTGT);
	setInterrapt(&dummyInterrapt7, 7, SD_486INTGT);
	setInterrapt(&dummyInterrapt8, 8, SD_486INTGT);
	setInterrapt(&dummyInterrapt9, 9, SD_486INTGT);
	setInterrapt(&dummyInterrapt10, 10, SD_486INTGT);
	setInterrapt(&dummyInterrapt11, 11, SD_486INTGT);
	setInterrapt(&dummyInterrapt12, 12, SD_486INTGT);
	setInterrapt(&dummyInterrapt13, 13, SD_486INTGT);
	setInterrapt(&dummyInterrapt14, 14, SD_486INTGT);
	setInterrapt(&dummyInterrapt15, 15, SD_486INTGT);
	setInterrapt(&dummyInterrapt16, 16, SD_486INTGT);
	setInterrapt(&dummyInterrapt17, 17, SD_486INTGT);
	setInterrapt(&dummyInterrapt18, 18, SD_486INTGT);
	setInterrapt(&dummyInterrapt19, 19, SD_486INTGT);
	setInterrapt(&dummyInterrapt20, 20, SD_486INTGT);
	setInterrapt(&dummyInterrapt21, 21, SD_486INTGT);
	setInterrapt(&dummyInterrapt22, 22, SD_486INTGT);
	setInterrapt(&dummyInterrapt23, 23, SD_486INTGT);
	setInterrapt(&dummyInterrapt24, 24, SD_486INTGT);
	setInterrapt(&dummyInterrapt25, 25, SD_486INTGT);
	setInterrapt(&dummyInterrapt26, 26, SD_486INTGT);
	setInterrapt(&dummyInterrapt27, 27, SD_486INTGT);
	setInterrapt(&dummyInterrapt28, 28, SD_486INTGT);
	setInterrapt(&dummyInterrapt29, 29, SD_486INTGT);
	setInterrapt(&dummyInterrapt30, 30, SD_486INTGT);
	setInterrapt(&dummyInterrapt31, 31, SD_486INTGT);
}

Interrapt *im;

void gp_interrapt(){
	uint32	error;
	reg_t	reg;
	int_err_in(error, reg);
	
	kprintf("General Protection Error: (code: %X)\n", error);
	for(;;);
	int_err_out();
}

void np_interrapt(){
	uint32	error;
	reg_t	*reg;
	int_err_in(error, reg);
	kprintf("Segment Not Present: (code: %X)\n", error);
	for(;;);
	int_err_out();
}

SystemCall *sc;


void sys_interrapt(){
	reg_t	*reg;
	sys_enter(reg);
	asm volatile ("mov %%esp, %0":"=m" (current->_esp):);
	//kprintf("stack_size: %i\n", current->getStackAddr() - current->_esp);
	//asm volatile ("mov %%esp, %0":"=m" (current->_esp):);
	//kprintf("stack_size: %i\n", current->getStackAddr() - current->_esp);
	//KSTOP;
	if(reg->eax > MAX_SYSCALLS){
		kprintf("ERROR: Bad syscall number %i", reg->eax);
		KSTOP;
	}
	sc->getSysCall(reg->eax)(reg);
	//kprintf("SHED_FLAG: %i\n", current->getOwner()->getFlag(NEED_RESCHED_PROC));
	if(current->getOwner()->getFlag(NEED_RESCHED_PROC)){
		kprintf("\nCALL RESCHEDULER\n");//KSTOP;
		pm->schedule();
		kprintf("\nSYS_CALL: RET FROM\n");
	}
	sys_out();
}

void nop_interrapt(){
	interrapt_in();
	uint32 reg = 3;
	kprintf("ERROR: NOP INTERRAPT - ");
	asm("push %cs");
	asm("pop %ax");
	asm("movl %%eax, %0":"=m" (reg));
	kprintf("reg: %X\n",reg);
	for(;;);
	interrapt_out();
}


